#ifndef __INIT_H__
#define __init_h__

#include "linux/compiler.h"


typedef int (*initcall_t)(void);
typedef void (*exitcall_t)(void);

#define __section(S) __attribute__ ((__section__(#S)))

#define __define_initcall(fn, id) \
	static initcall_t __initcall_##fn##id __used \
	__attribute__((__section__(".initcall" #id ".init"))) = fn

#define __init		__section(.init.text) 
#define __initdata	__section(.init.data)
#define __exitdata	__section(.exit.data)
#define __exit_call __section(.exitcall.exit)

#define pure_initcall(fn)		__define_initcall(fn, 0)

#define core_initcall(fn)		__define_initcall(fn, 1)
#define core_initcall_sync(fn)		__define_initcall(fn, 1s)
#define postcore_initcall(fn)		__define_initcall(fn, 2)
#define postcore_initcall_sync(fn)	__define_initcall(fn, 2s)
#define arch_initcall(fn)		__define_initcall(fn, 3)
#define arch_initcall_sync(fn)		__define_initcall(fn, 3s)
#define subsys_initcall(fn)		__define_initcall(fn, 4)
#define subsys_initcall_sync(fn)	__define_initcall(fn, 4s)
#define fs_initcall(fn)			__define_initcall(fn, 5)
#define fs_initcall_sync(fn)		__define_initcall(fn, 5s)
#define rootfs_initcall(fn)		__define_initcall(fn, rootfs)
#define device_initcall(fn)		__define_initcall(fn, 6)
#define device_initcall_sync(fn)	__define_initcall(fn, 6s)
#define late_initcall(fn)		__define_initcall(fn, 7)
#define late_initcall_sync(fn)		__define_initcall(fn, 7s)

#define __initcall(fn) device_initcall(fn)


#define module_init(x)	__initcall(x);


#define __exit_call	 __section(.exitcall.exit)

#define __exitcall(fn) \
	static exitcall_t __exitcall_##fn __used __exit_call = fn

#define module_exit(x)	__exitcall(x);


#define __initdata	__section(.init.data)

extern int do_one_initcall(initcall_t fn);


#endif
